/*
  ***************************************************************************************************************************************
  * File Name          : ieee1459.h
  * Description        : This file provides head for the ieee1459 algorithm.
  * Author             : jackwang by jiawang16@foxmail.com
  * Date               : 2021-03-29
  * Version            : 1.0.0
  ***************************************************************************************************************************************
*/

#ifndef __IEEE1459_H__
#define __IEEE1459_H__

#ifndef PI 
#define PI 3.1415 
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*! include headers */
/*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <stdint.h>
#include "FFT.h"

#ifdef ARM_MATH_CM4
#include "arm_math.h"  
#include "arm_const_structs.h"
#else
#include <math.h>
typedef float float32_t;
typedef double float64_t;
#endif

/*! ieee1459 algorithm macro define */
/*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define MAX_Harmonic_Idx                            50
#define Fundamental_Idx                             1
#define DC_Offset_Idx                               1
#define Block_Size                                  4096

/*! ieee1459 algorithm struct define */
/*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#pragma pack(1)
typedef struct{
    fft_point_t *Ua_fft_out;
    fft_point_t *Ub_fft_out;
    fft_point_t *Uc_fft_out;

    fft_point_t *Ia_fft_out;
    fft_point_t *Ib_fft_out;
    fft_point_t *Ic_fft_out;
    fft_point_t *In_fft_out;

    fft_point_t *Uab_fft_out;
    fft_point_t *Uac_fft_out;
    fft_point_t *Ubc_fft_out;
}fft_data_handle_t;

typedef struct
{
    float32_t Pa_1;
    float32_t Pb_1;
    float32_t Pc_1;
    
    float32_t Qa_1;
    float32_t Qb_1;
    float32_t Qc_1;
    
    float32_t Sa_1;
    float32_t Sb_1;
    float32_t Sc_1;
    
    float32_t P_1;
    float32_t Q_1;
    float32_t S_1;

    float32_t factor;
}fundamental_result_t;

typedef struct
{
    fft_point_t Up_1;
    fft_point_t Un_1;
    fft_point_t Uz_1;
    
    fft_point_t Ip_1;
    fft_point_t In_1;
    fft_point_t Iz_1;
    
    float32_t pha;/*! note, should be angle, not radians */
    
}sequence_result_t;

typedef struct
{
    float32_t Pp_1;
    float32_t Qp_1;
    float32_t Sp_1;
}sequence_power_t;

typedef struct
{
    float32_t Ip_P_1;/*! Ip_1 of active power */
    float32_t Ip_Q_1;/*! Ip_1 of reactive power */
    float32_t Ip_U_1;/*! unbalance current of Ip_1 */
}sequence_current_t;

typedef struct
{
    float32_t Ia_h;
    float32_t Ib_h;
    float32_t Ic_h;
    float32_t Iall_h;
}harmonic_current_t;

typedef struct
{
    float32_t Ua;
    float32_t Ub;
    float32_t Uc;
    
    float32_t Uab;
    float32_t Uac;
    float32_t Ubc;
    
    float32_t Ia;
    float32_t Ib;
    float32_t Ic;
    float32_t In;
}equivalent_apparent_power_paras_t;

typedef struct
{
    float32_t Se;
    float32_t Se_1;
    float32_t Su_1;
    float32_t Se_N;
    float32_t PFe;
    float32_t PFp_1;
    float32_t PFp_e;
    float32_t Hpol;
}equivalent_paras_t;

typedef struct 
{
    float32_t Pa;
    float32_t Pb;
    float32_t Pc;
    float32_t Pall;
}normal_active_power_t;

typedef struct
{
    float32_t Ua;
    float32_t Ub;
    float32_t Uc;
    
    float32_t Ia;
    float32_t Ib;
    float32_t Ic;
    float32_t In;

    float32_t Uab;
    float32_t Uac;
    float32_t Ubc;
}rms_t;

typedef struct
{
    rms_t                 rms;
    normal_active_power_t normal_active_power;
    fundamental_result_t  fundamental_result;
    sequence_power_t      sequence_power;
    harmonic_current_t    harmonic_current;
    equivalent_paras_t    equivalent_paras;
}ieee1459_result_t;/*! send to serve */
#pragma pack()

/*! extern variable declaration */
/*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
extern fft_data_handle_t fft_data_handle;

extern float32_t adcBuff_Ua[Block_Size];
extern float32_t adcBuff_Ub[Block_Size];
extern float32_t adcBuff_Uc[Block_Size];
extern float32_t adcBuff_Uab[Block_Size];
extern float32_t adcBuff_Uac[Block_Size];
extern float32_t adcBuff_Ubc[Block_Size];
extern float32_t adcBuff_Ia[Block_Size];
extern float32_t adcBuff_Ib[Block_Size];
extern float32_t adcBuff_Ic[Block_Size];
extern float32_t adcBuff_In[Block_Size];

extern fft_point_t Ua_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Ub_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Uc_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Ia_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Ib_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Ic_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t In_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Uab_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Uac_fft_out_buff[MAX_Harmonic_Idx];
extern fft_point_t Ubc_fft_out_buff[MAX_Harmonic_Idx];

/*! ieee1459 caculate function prototype */
/*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void IEEE1459_data_handle_init(fft_data_handle_t* pHandle);
void IEEE1459_calculate_line_voltage(const float32_t* pSrcA, const float32_t* pSrcB, float32_t* pDst, uint32_t blockSize);
void IEEE1459_caculate_normal_active_power(const float32_t SrcV, const float32_t SrcI, float32_t* pResult);
void IEEE1459_caculate_fundamental_result(const fft_data_handle_t* pHandle, fundamental_result_t* pResult);
void IEEE1459_caculate_sequence_positive(const fft_point_t srcA, const fft_point_t srcB, const fft_point_t srcC, fft_point_t* pResult);
void IEEE1459_caculate_sequence_negtive(const fft_point_t srcA, const fft_point_t srcB, const fft_point_t srcC, fft_point_t* pResult);
void IEEE1459_caculate_sequence_zero(const fft_point_t srcA, const fft_point_t srcB, const fft_point_t srcC, fft_point_t* pResult);
void IEEE1459_caculate_sequence_result(const fft_data_handle_t* pHandle, sequence_result_t* pResult);
void IEEE1459_caculate_sequence_positive_power(const sequence_result_t* pResult, sequence_power_t* pPower);
void IEEE1459_caculate_sequence_current(const sequence_result_t* pResult, sequence_current_t* pCurrent);
void IEEE1459_caculate_harmonic_current(const float32_t Ix, const float32_t Ix_1, float32_t* pRestlt);
void IEEE1459_caculate_total_harmonic_current(const harmonic_current_t* pCurrent, float32_t* pResult);
void IEEE1459_caculate_equivalent_apparent_power(const equivalent_apparent_power_paras_t* pParas, float32_t* pResult);
void IEEE1459_caculate_unbalance_equivalent_apparent_power(const float32_t Se_1, const float32_t Sp_1, float32_t* pResult);
void IEEE1459_caculate_harmonic_equivalent_apparent_power(const float32_t Se, const float32_t Se_1, float32_t* pResult);
void IEEE1459_caculate_equivalent_power_factor(const float32_t P, const float32_t Se, float32_t* pResult);
void IEEE1459_caculate_fundamental_power_factor(const float32_t Pp_1, const float32_t Sp_1, float32_t* pResult);
void IEEE1459_caculate_effictive_power_factor(const float32_t Pp_1, const float32_t Se, float32_t* pResult);
void IEEE1459_caculate_harmonic_pollute_factor(const float32_t Se_N, const float32_t Se_1, float32_t* pResult);
void IEEE1459_caculate_all(const fft_data_handle_t *pHandle, ieee1459_result_t* pResult);

#ifdef __cplusplus
}
#endif

#endif
/*! end of the file */

/*! end of the file */
